package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;


@DubboService
public class MovementServiceImpl implements MovementService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    RedisIdService redisIdService;//全局id自增器

    @Override
    public void save(Movement movement) {
        //1.先将movement保存到”动态表”中(pid)
        //1.1 movement设置大数据id(pid)
        movement.setPid(redisIdService.getNextId(ConstantUtil.MOVEMENT_ID));
        mongoTemplate.save(movement);

        //2.将动态保存到”我的动态表”中
        //2.1 封装我的动态对象
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId(movement.getId());//动态id
        myMovement.setCreated(movement.getCreated());//创建时间

        //2.2 保存(每个用户都有一张我的动态表)
        mongoTemplate.save(myMovement,ConstantUtil.MOVEMENT_MINE+movement.getUserId());
        
        //3.查询我的好友们
        //3.1 创建条件对象
        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));

        //3.2 查询好友表找到自己的好友们
        List<Friend> friends = mongoTemplate.find(query, Friend.class);

        //4.遍历我的好友们,获取每个好友的id,将动态保存到好友的”好友动态表”中
        if (CollUtil.isNotEmpty(friends)) {
            for (Friend friend : friends) {
                //4.1 获取好友id
                Long friendId = friend.getFriendId();

                //4.2 封装好友动态对象
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId(movement.getId());//动态的id
                friendMovement.setUserId(movement.getUserId());//发布者id
                friendMovement.setCreated(movement.getCreated());//发布时间

                //4.3 保存数据(每个用户都有一张)
                mongoTemplate.save(friendMovement,ConstantUtil.MOVEMENT_FRIEND+friendId);
            }
        }
    }

    @Override
    public PageBeanVo findMyMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.创建条件对象(分页和排序)
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip((pageNum - 1) * pageSize).limit(pageSize);
        //2.查询我的动态表,获取我的所有动态
        List<MyMovement> myMovements = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        //3.遍历我的动态集合,获取每个动态id,通过id查询动态详情表获取详情,将每个详情放入一个集合中
        //3.1 创建一个Movement集合
        List<Movement> movementList = new ArrayList<>();

        //3.2 遍历我的动态集合,获取每个动态
        if (CollUtil.isNotEmpty(myMovements)) {
            for (MyMovement myMovement : myMovements) {
                //3.3 根据动态id去动态表中查询详情
                ObjectId publishId = myMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);

                //3.4 将已审核的动态详情放入movement集合中
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4.封装pageBeanVo返回
        Long counts = Long.valueOf(movementList.size());
        return new PageBeanVo(pageNum,pageSize,counts,movementList);
    }

    @Override
    public PageBeanVo findFriendMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.创建条件对象([排序,分页)
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).limit(pageSize).skip((pageNum - 1) * pageSize);

        //2.查询我的好友动态表,获取好友动态list
        List<FriendMovement> friendMovements = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //3.遍历list获取每个动态id,查询动态详情表获取每个动态详情,将详情放入新集合
        //3.1 创建movement集合
        List<Movement> movementList = new ArrayList<>();
        //3.2 遍历好友动态表,获取每个动态id
        if (CollUtil.isNotEmpty(friendMovements)) {
            for (FriendMovement friendMovement : friendMovements) {
                //3.3 通过id查询动态详情表,获取每个动态详情
                ObjectId publishId = friendMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);

                //3.4 将已审核的动态详情放入movement集合中
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4.封装pageBeanVo且返回
        Long counts = Long.valueOf(movementList.size());
        return new PageBeanVo(pageNum,pageSize,counts,movementList);
    }

    @Override
    public PageBeanVo findRecommendMovementByPage(Long userId, Integer pageNum, Integer pageSize) {
        //1.创建条件对象(排序,分页,当前登陆者)
        Query query = new Query(Criteria.where("userId").is(userId))
                .with(Sort.by(Sort.Order.desc("created"))).skip((pageNum-1)*pageSize).limit(pageSize);

        //2.查询推荐表,获取推荐动态集合
        List<RecommendMovement> recommendMovements = mongoTemplate.find(query, RecommendMovement.class);

        //3.遍历推荐动态集合,获取每个动态id,通过id查询动态详情,将动态详情放入集合中
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendMovements)) {
            for (RecommendMovement recommendMovement : recommendMovements) {
                ObjectId publishId = recommendMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);

                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }
        //4.封装PageBeanVo且返回
        Long counts = Long.valueOf(movementList.size());
        return new PageBeanVo(pageNum,pageSize,counts,movementList);
    }

    @Override
    public Movement findById(ObjectId publishId) {
        return mongoTemplate.findById(publishId,Movement.class);
    }

    @Override
    public PageBeanVo findMovementByPage(Long userId, Integer state, Integer pageNum, Integer pageSize) {
        //1.创建条件对象(分页,排序)
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum-1)*pageSize).limit(pageSize);

        //2.若userId不为空添加userId条件
        if (userId != null) {
            query.addCriteria(Criteria.where("userId").is(userId));
        }

        //3.若state不为空添加state条件
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }

        //4.查询movement表返回当前页list
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //5.查询movement表中满足条件的条数,查询总记录数的时候自动删除分页条件
        long count = mongoTemplate.count(query, Movement.class);

        //6.封装PageBeanVo
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    @Override
    public void update(Movement movement) {
        mongoTemplate.save(movement);
    }
}
